package com.whfc.emp.service.impl;

import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.MathUtil;
import com.whfc.common.util.PageUtil;
import com.whfc.emp.dao.*;
import com.whfc.emp.dto.AppEmpDTO;
import com.whfc.emp.dto.AppTrainDTO;
import com.whfc.emp.dto.AppTrainEmpDTO;
import com.whfc.emp.dto.TrainEmpDTO;
import com.whfc.emp.entity.*;
import com.whfc.emp.enums.AppAttachmentType;
import com.whfc.emp.manager.TrainBoxManager;
import com.whfc.emp.param.*;
import com.whfc.emp.service.AppTrainService;
import com.whfc.fuum.service.SysDeptService;
import com.whfc.fuum.service.SysDictService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClasssName AppTrainServiceImpl
 * @Description 人员管理-培训
 * @Author hw
 * @Date 2020/11/26 16:18
 * @Version 1.0
 */
@DubboService(interfaceClass = AppTrainService.class, version = "1.0.0", timeout = 5000)
public class AppTrainServiceImpl implements AppTrainService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AppTrainMapper appTrainMapper;

    @Autowired
    private AppTrainEmpMapper appTrainEmpMapper;

    @Autowired
    private AppTrainEmpImgMapper appTrainEmpImgMapper;

    @Autowired
    private AppEmpMapper appEmpMapper;

    @Autowired
    private TrainBoxManager trainBoxManager;

    @Autowired
    private AppTrainAttachmentMapper appTrainAttachmentMapper;

    @NacosValue("${emp.enter.train.type.id}")
    private Integer enterTrainTypeId;

    @DubboReference(interfaceClass = SysDictService.class, version = "1.0.0")
    private SysDictService sysDictService;

    @DubboReference(interfaceClass = SysDeptService.class, version = "1.0.0")
    private SysDeptService sysDeptService;

    @Override
    public PageData<AppTrainDTO> list(AppTrainListParam request) {
        logger.info("人员管理-培训列表,request:{}", request);
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<AppTrainDTO> list = appTrainMapper.selectByParam(request);
        list.forEach(appTrainDTO -> {
            Integer trainType = appTrainDTO.getTrainType();
            String trainTypeName = sysDictService.getDictName(trainType);
            appTrainDTO.setTrainTypeName(trainTypeName);
            String deptName = sysDeptService.getDeptNameById(appTrainDTO.getDeptId());
            appTrainDTO.setDeptName(deptName);
            List<AppTrainAttachment> attachments = appTrainAttachmentMapper.selectByTrainId(appTrainDTO.getTrainId());
            if (attachments != null && !attachments.isEmpty()) {
                List<String> trainPhoto = attachments.stream().filter(appTrainAttachment ->
                        AppAttachmentType.PHOTO.getValue().equals(appTrainAttachment.getType())).map(AppTrainAttachment::getUrl).collect(Collectors.toList());
                List<String> attachment = attachments.stream().filter(appTrainAttachment ->
                        AppAttachmentType.ATTACHMENT.getValue().equals(appTrainAttachment.getType())).map(AppTrainAttachment::getUrl).collect(Collectors.toList());
                appTrainDTO.setTrainPhoto(trainPhoto);
                appTrainDTO.setAttachment(attachment);
            }
        });
        PageHelper.clearPage();
        return PageUtil.pageData(PageInfo.of(list));
    }

    @Override
    public PageData<AppTrainEmpDTO> list(Integer empId, Integer pageNum, Integer pageSize) throws BizException {
        logger.info("人员管理-培训列表,empId:{}，pageNum：{}，pageSize：{}", empId, pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<AppTrainEmpDTO> list = appTrainMapper.selectByEmpId(empId);
        PageHelper.clearPage();
        //获取工种类型 以及培训图片
        for (AppTrainEmpDTO appTrainEmpDTO : list) {
            Integer trainType = appTrainEmpDTO.getTrainType();
            String trainTypeName = sysDictService.getDictName(trainType);
            appTrainEmpDTO.setTrainTypeName(trainTypeName);

            List<String> imgUrlList = appTrainEmpImgMapper.selectImgUrlList(appTrainEmpDTO.getTrainEmpId());
            appTrainEmpDTO.setImgUrlList(imgUrlList);
        }
        return PageUtil.pageData(PageInfo.of(list));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AppTrainAddParam request) {
        logger.info("人员管理-新增培训,request:{}", request);
        AppTrain record = new AppTrain();
        BeanUtils.copyProperties(request, record);
        List<String> trainPhoto = request.getTrainPhoto();
        List<String> attachment = request.getAttachment();
        appTrainMapper.insertSelective(record);
        if (trainPhoto != null && !trainPhoto.isEmpty()) {
            appTrainAttachmentMapper.insertAll(record.getId(), AppAttachmentType.PHOTO.getValue(), trainPhoto);
        }
        if (attachment != null && !attachment.isEmpty()) {
            appTrainAttachmentMapper.insertAll(record.getId(), AppAttachmentType.ATTACHMENT.getValue(), attachment);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(AppTrainEditParam request) {
        logger.info("人员管理-编辑培训,request:{}", request);
        AppTrain record = new AppTrain();
        BeanUtils.copyProperties(request, record);
        record.setId(request.getTrainId());
        appTrainMapper.updateByPrimaryKeySelective(record);
        List<String> trainPhoto = request.getTrainPhoto();
        List<String> attachment = request.getAttachment();
        appTrainAttachmentMapper.delByTrainId(request.getTrainId());
        if (trainPhoto != null && !trainPhoto.isEmpty()) {
            appTrainAttachmentMapper.insertAll(record.getId(), AppAttachmentType.PHOTO.getValue(), trainPhoto);
        }
        if (attachment != null && !attachment.isEmpty()) {
            appTrainAttachmentMapper.insertAll(record.getId(), AppAttachmentType.ATTACHMENT.getValue(), attachment);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void del(Integer trainId) {
        logger.info("人员管理-删除培训,trainId:{}", trainId);
        appTrainMapper.deleteLogicById(trainId);
        appTrainAttachmentMapper.delByTrainId(trainId);
    }

    @Override
    public void complete(Integer trainId) {
        logger.info("人员管理-完成培训,trainId:{}", trainId);
        appTrainMapper.updateState(trainId);
    }

    @Override
    public PageData<AppTrainEmpDTO> trainEmpList(AppTrainEmpListParam request) {
        logger.info("人员管理-培训人员列表,request:{}", request);
        PageData<AppTrainEmpDTO> pageData = new PageData<>();
        Integer trainId = request.getTrainId();

        //查询培训员工的列表
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<TrainEmpDTO> trainEmpList = appTrainEmpMapper.selectTrainEmpByParam(request);
        PageHelper.clearPage();
        //查找成绩图片
        for (TrainEmpDTO trainEmpDTO : trainEmpList) {
            List<String> imgUrlList = appTrainEmpImgMapper.selectImgUrlList(trainEmpDTO.getTrainEmpId());
            trainEmpDTO.setImgUrlList(imgUrlList);
        }
        PageInfo<TrainEmpDTO> pageInfo = PageInfo.of(trainEmpList);

        //查找培训的总体信息
        AppTrainEmpDTO detail = new AppTrainEmpDTO();
        AppTrain appTrain = appTrainMapper.selectByPrimaryKey(trainId);
        String trainTypeName = sysDictService.getDictName(appTrain.getTrainType());
        BeanUtils.copyProperties(appTrain, detail);
        detail.setTrainId(trainId);
        detail.setTrainTypeName(trainTypeName);
        //查询培训通过的员工数
        Integer totalNum = appTrainEmpMapper.countEmp(trainId);
        Integer passNum = appTrainEmpMapper.countPassEmp(trainId);
        double qualifiedRate = totalNum == 0 ? 0 : MathUtil.round(1.0 * passNum / totalNum, 3);
        detail.setEmpNum(totalNum);
        detail.setQualifiedRate(qualifiedRate);
        detail.setEmpList(trainEmpList);
        pageData.setDetail(detail);
        pageData.setTotal(pageInfo.getTotal());
        pageData.setPages(pageInfo.getPages());
        return pageData;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void trainEmpAdd(AppTrainEmpAddParam request) {
        logger.info("人员管理-添加培训人员,request:{}", request);
        Integer trainId = request.getTrainId();
        AppTrain appTrain = appTrainMapper.selectByPrimaryKey(trainId);
        if (appTrain == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该培训记录不存在.");
        }
        List<Integer> empIdList = request.getEmpIdList();
        for (Integer empId : empIdList) {
            Integer count = appTrainEmpMapper.countByTrainIdAndEmpId(trainId, empId);
            if (count > 0) {
                continue;//该员工已存在
            }
            AppEmp appEmp = appEmpMapper.selectByPrimaryKey(empId);
            String empName = appEmp.getEmpName();
            AppTrainEmp record = new AppTrainEmp();
            record.setEmpId(empId);
            record.setEmpName(empName);
            record.setTrainId(trainId);
            appTrainEmpMapper.insertSelective(record);
            //如果当前培训是 入场三级教育  需要更新人员 入场三级教育培训状态
            if (enterTrainTypeId.equals(appTrain.getTrainType())) {
                appEmpMapper.updateEmpEnterTrainFlag(empId, 1);
            }
        }
    }

    @Override
    public void trainEmpDel(AppTrainEmpDelParam request) {
        logger.info("人员管理-删除培训人员,request:{}", request);
        appTrainEmpMapper.deleteByTrainIdAndEmpId(request.getTrainId(), request.getEmpId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void score(AppTrainScoreParam request) {
        logger.info("人员管理-添加修改培训分数,request:{}", request);

        AppTrainEmp appTrainEmp = appTrainEmpMapper.selectTrainEmp(request.getTrainId(), request.getEmpId());
        if (appTrainEmp == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该培训记录人员不存在");
        }

        Double score = request.getScore();
        Integer passFlag = request.getPassFlag();
        Integer trainId = request.getTrainId();
        Integer empId = request.getEmpId();
        AppTrain appTrain = appTrainMapper.selectByPrimaryKey(trainId);
        if (appTrain == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该培训记录不存在.");
        }
        appTrainEmpMapper.updateScoreByTrainIdAndEmpId(score, passFlag, trainId, empId);

        //如果当前培训是 入场三级教育  需要更新人员 入场三级教育培训状态
        if (enterTrainTypeId.equals(appTrain.getTrainType())) {
            appEmpMapper.updateEmpEnterTrainFlag(empId, passFlag);
        }
        //保存培训图片
        saveEmpImg(appTrainEmp.getId(), request.getImgUrlList());
    }

    @Override
    public PageData<AppEmpDTO> getEmpList(Integer pageNum, Integer pageSize, Integer trainId, String keyword, Integer groupId) {
        logger.info("人员管理-添加修改培训分数,pageNum:{},pageSize:{},trainId:{},keyword:{},groupId:{}",
                pageNum, pageSize, trainId, keyword, groupId);
        Integer deptId = appTrainMapper.selectDeptIdByTrainId(trainId);
        PageHelper.startPage(pageNum, pageSize);
        List<AppEmpDTO> list = appEmpMapper.selectAddTrainEmp(deptId, trainId, keyword, groupId);
        PageHelper.clearPage();
        PageInfo<AppEmpDTO> pageInfo = PageInfo.of(list);
        return PageUtil.pageData(pageInfo);
    }

    @Override
    public void saveSignImg(Integer trainEmpId, String signImgUrl) throws BizException {
        logger.info("人员管理-保存签名图片,trainEmpId:{},signImgUrl:{}", trainEmpId, signImgUrl);
        AppTrainEmp trainEmp = appTrainEmpMapper.selectByPrimaryKey(trainEmpId);
        if (trainEmp == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该培训人员不存在");
        }
        trainEmp.setSignImgUrl(signImgUrl);
        appTrainEmpMapper.updateByPrimaryKeySelective(trainEmp);
    }

    @Override
    public void saveTrainEmpImg(Integer trainEmpId, List<String> imgUrlList) throws BizException {
        saveEmpImg(trainEmpId, imgUrlList);
    }

    @Override
    public void handleFailedData() throws BizException {
        trainBoxManager.handleFailedData();
    }

    @Override
    public TrainEmpDTO getTrainEmpInfo(Integer trainEmpId) throws BizException {
        AppTrainEmp trainEmp = appTrainEmpMapper.selectByPrimaryKey(trainEmpId);
        if (trainEmp == null) {
            return null;
        }
        TrainEmpDTO trainEmpDTO = new TrainEmpDTO();
        BeanUtils.copyProperties(trainEmp, trainEmpDTO);
        trainEmpDTO.setTrainEmpId(trainEmp.getId());
        return trainEmpDTO;
    }

    /**
     * 保存培训成绩图片
     *
     * @param trainEmpId 培训人员ID
     * @param imgUrlList 图片列表
     */
    private void saveEmpImg(Integer trainEmpId, List<String> imgUrlList) {
        //删除旧的成绩图片
        appTrainEmpImgMapper.logicDel(trainEmpId);
        if (imgUrlList == null || imgUrlList.isEmpty()) {
            return;
        }
        for (String imgUrl : imgUrlList) {
            AppTrainEmpImg trainEmpImg = new AppTrainEmpImg();
            trainEmpImg.setTrainEmpId(trainEmpId);
            trainEmpImg.setImgUrl(imgUrl);
            appTrainEmpImgMapper.insertSelective(trainEmpImg);
        }
    }
}
